package jvm.concurrent;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Atomic变量自增运算测试
 *
 * @author msi
 */
public class AtomicTest {

    public static AtomicInteger race = new AtomicInteger(0);

    public static void increase() {
        race.incrementAndGet();
    }

    private static final int THREADS_COUNT = 20;

    public static void main(String[] args) throws Exception {
        Thread[] threads = new Thread[THREADS_COUNT];
        for (int i = 0; i < THREADS_COUNT; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10000; i++) {
                        increase();
                    }
                }
            });
            threads[i].start();
        }

        while (Thread.activeCount() > 1)
            Thread.yield();

        System.out.println(race);
    }

    /**
     * 锁消除技术
     */
    public String concatString(String s1,String s2,String s3){
        return s1+s2+s3;
    }

    /**
     * JDK 5之前使用StringBuffer JDK5之后使用StringBuilder
     * 在这段代码中就会使用到加锁操作。但是经过即时编译器的逃逸分析技术，会将append方法的syn加锁消除。
     *     public String concatString(String s1,String s2,String s3){
     *         StringBuffer sb =new StringBuffer();
     *         sb.append(s1);
     *         sb.append(s2);
     *         sb.append(s3);
     *         return sb.toString();
     *     }
     */

}

/**
 * 结果 200000 由于原子类中采用CAS算法，所以不会出现线程安全问题。
 * 不过CAS算法也不是完美的。会有ABA问题的出现。即V地址的变量从A--B--A，这时区更新该变量 这个线程会以为这里的值没有变动，但是其实是变动了的。可以通过加version号解决。如原子引用类 AtomicStampedReference，
 * 通过控制版本version，来保证CAS的正确性。
 */
